from datetime import datetime
from os.path import join, dirname
from typing import Optional, Union, Tuple

from .DBManager import DBManager, DBResult


class BaseEntity(object):
    db = DBManager()

    # close提升为类方法，
    @classmethod
    def close(cls):
        if cls.is_connect():
            cls.db.close()

    @classmethod
    def is_connect(cls):
        return cls.db.isConnect()

    @staticmethod
    def get_current_time():
        return datetime.now().isoformat(sep=' ', timespec='minutes')

    def __init__(self, table_name: str, db_file=None):
        self.table_name = table_name
        if not db_file:
            db_file = join(dirname(__file__), 'db.sqlite3')
        BaseEntity.db.connect(db_file)

    @property
    def db_file(self):
        return self.db.db_file

    def get_all(self) -> tuple:
        r = self.get()
        return r.as_dict()

    def get(self, col: Optional[Union[tuple, list, str]] = (),
            condition: Optional[Union[tuple, list, dict]] = (),
            **kwargs) -> Optional[Union[DBResult, Tuple]]:
        # 单列查询，返回tuple or 单值，多列查询，返回DBResult
        if isinstance(col, str):
            _col = (col,)
            result = self.db.select(self.table_name, _col, condition, **kwargs)
            if len(result)>1:
                return tuple([r[col] for r in result])
            else:
                return result[0][col]
        else:
            return self.db.select(self.table_name, col, condition, **kwargs)

    def get_one(self, **kwargs) -> Optional[dict]:
        """
        使用kwargs作为查询条件，返回一个结果
        """
        result = self.get(condition=kwargs)
        if len(result) >= 1:
            return result[0]
        else:
            return None

    def get_multi(self, **kwargs) -> Tuple[dict]:
        """
        使用kwargs作为查询条件，返回多个结果
        """
        return self.get(condition=kwargs).as_dict()

    def add_one(self, data: Optional[dict]=None, **kwargs):
        return self.db.insert(self.table_name, data, **kwargs)

    def add_multi(self, col: tuple, data: tuple):
        return self.db.insert_batch(self.table_name, col, data)

    def set(self, condition: Optional[Union[dict, tuple]] = (), **kwargs):
        return self.db.update(self.table_name, condition, **kwargs)

    def delete(self, condition: tuple = ()):
        return self.db.delete(self.table_name, condition)

    def count(self, condition: tuple = ()):
        return self.db.count(self.table_name, condition)
